package com.colphin.androidplugin;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;

import com.unity3d.player.UnityPlayer;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashSet;
import java.util.Set;

/**
 * Android 广播相关帮助类
 */
public class BroadcastHelper {

    private static final String TAG = "BroadcastHelper";

    public static void test() {
        Log.e(TAG, "test: ");
        Intent intent = new Intent("com.t.adgamecenter.client");
        intent.setPackage("com.gandong.Superwings");
        intent.putExtra("version", "0.1");
        intent.putExtra("sender", "com.gandong.adgamecenter");
        intent.putExtra("cmd", "OnQuit");
        intent.putExtra("value", "");
        UnityPlayer.currentActivity.sendBroadcast(intent);
    }

    /**
     * 接收广播类
     */
    public static class Receiver extends BroadcastReceiver {

        // 广播是否已注册
        private boolean mIsRegister = false;
        // 注册监听广播的类名
        private String mListenerClass = null;
        // 监听广播的类中接收信息的方法
        private String mListenerMethod = null;
        // 注册监听消息列表
        private Set<String> mListeners = new HashSet<>();

        public Receiver() {
            Log.i(TAG, "instance initializer: Receiver");
        }

        /**
         * 注册监听广播
         *
         * @param action 需要监听的action
         */
        public void register(String action) {
            Log.i(TAG, "register: ");
            IntentFilter filter = new IntentFilter(action);
            UnityPlayer.currentActivity.registerReceiver(this, filter);
            mIsRegister = true;
        }

        /**
         * 注销监听，不再使用及时注销，程序结束前必须注销
         */
        public void unRegister() {
            Log.i(TAG, "unRegister: ");
            setListenerClass(null, null);
            removeListenerAll();
            if (mIsRegister) {
                UnityPlayer.currentActivity.unregisterReceiver(this);
                mIsRegister = false;
            }
        }

        /**
         * 查询监听是否注册
         *
         * @return 注册状态, true 已注册， false 未注册。
         */
        public boolean isRegister() {
            return mIsRegister;
        }

        /**
         * 设置接收广播消息的类
         *
         * @param classname 接收广播消息的类名
         * @param method    监听广播的类中接收信息的方法,
         *                  方法收到的信息为json格式的string,
         *                  json中的keys是通过addListener方法添加的
         */
        public void setListenerClass(String classname, String method) {
            mListenerClass = classname;
            mListenerMethod = method;
        }

        /**
         * 添加监听的消息
         *
         * @param key 广播Extra中的消息名
         */
        public void addListener(String key) {
            if (TextUtils.isEmpty(key)) {
                return;
            }
            mListeners.add(key);
        }

        /**
         * 移除特定消息监听
         *
         * @param key 广播Extra中的消息名
         */
        public void removeListener(String key) {
            if (TextUtils.isEmpty(key)) {
                return;
            }
            mListeners.remove(key);
        }

        /**
         * 移除所有消息监听
         */
        public void removeListenerAll() {
            mListeners.clear();
        }

        private String parse(Intent intent, String key) {
            if (null == intent) {
                return null;
            }
            return intent.getStringExtra(key);
        }

        private boolean checkRegisterReceiver() {
            if (TextUtils.isEmpty(mListenerClass) || TextUtils.isEmpty(mListenerMethod)) {
                Log.e(TAG, "checkRegisterReceiver: Listener class or method is null, are you set?");
                return false;
            }
            return true;
        }

        private void sendMessage(String data) {
            Log.i(TAG, "sendMessage: ");
            if (!checkRegisterReceiver()) {
                return;
            }
            UnityPlayer.UnitySendMessage(mListenerClass, mListenerMethod, data);
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            Bundle extras = intent.getExtras();
            Set<String> keySet = extras.keySet();
            if (null == keySet) {
                return;
            }

            if (!checkRegisterReceiver()) {
                return;
            }

            JSONObject jsonObject = new JSONObject();
            for (String key : mListeners) {
                String value = null;
                if (keySet.contains(key)) {
                    value = parse(intent, key);
                }
                try {
                    jsonObject.put(key, null == value ? "" : value);
                } catch (JSONException e) {
//                        e.printStackTrace();
                }
            }
            sendMessage(jsonObject.toString());
        }
    }

    /**
     * 发送广播类
     */
    public static class Sender {
        Intent mIntent = null;

        public Sender() {
            Log.i(TAG, "instance initializer: Sender");
        }

        /**
         * 开始准备发送广播
         *
         * @param action 发送广播的action
         * @param rPkg   接收广播的包名
         * @return 准备状态，true 准备成功， 可以设置其他信息后发送，false 准备失败，当前被其他占用
         */
        public boolean prepare(String action, String rPkg) {
            Log.i(TAG, "prepare: ");
            if (null == mIntent) {
                mIntent = new Intent(action);
                mIntent.setPackage(rPkg);
                return true;
            }
            Log.i(TAG, "prepare: is busy!");
            return false;
        }

        /**
         * 广播进入准备状态后，设置广播flags
         *
         * @param flags 类似Intent.FLAG_INCLUDE_STOPPED_PACKAGES， 可以用'|'进行组合
         */
        public void setFlags(int flags) {
            if (null == mIntent) {
                return;
            }
            mIntent.setFlags(flags);
        }

        /**
         * 广播进入准备状态后，设置附加信息
         *
         * @param key   附加信息名
         * @param value 附加信息名对应的值
         */
        public void putExtra(String key, String value) {
            if (null == mIntent) {
                return;
            }
            mIntent.putExtra(key, value);
        }

        /**
         * 广播进入准备状态后，flags及extra设置完成后，发送广播
         */
        public void send() {
            Log.i(TAG, "send: ");
            if (null == mIntent) {
                Log.e(TAG, "send: intent is null, are you prepare?");
                return;
            }
            UnityPlayer.currentActivity.sendBroadcast(mIntent);
            reset();
        }

        /**
         * 重置广播状态，可以重新尝试进入准备状态
         */
        public void reset() {
            Log.i(TAG, "reset: ");
            mIntent = null;
        }
    }
}